package java2020spring;
import java.util.*;
import java.util.regex.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Math;


public class Calculator implements ActionListener,KeyListener{
	
	JFrame frame=new JFrame("0222徐佳一的计算器");
	JTextField TextField_Result=new JTextField();//结果文本框
	String[] signs={"x²","%","!","C","back","1/x","√x","(",")","/","π","7",
			"8","9","*","cos","4","5","6","-","sin","1","2","3","+","°","+/-","0",".","="};
	JButton buttons[]=new JButton[signs.length];//按钮
	
	public Calculator(){
		Color color1=new Color(200,214,228);//按钮颜色
		Color color2=new Color(143,191,229);//等于号颜色
		Color color3=new Color(244,245,246);//背景颜色
		Color color4=new Color(244,247,250);//数字颜色
		Color color5=new Color(225,225,225);//边框颜色
				
		TextField_Result.setHorizontalAlignment(JTextField.RIGHT);//右对齐
		TextField_Result.setEditable(false);
		TextField_Result.setPreferredSize(new Dimension(500,100));//结果文本框大小
		TextField_Result.setBackground(color3);
		TextField_Result.addKeyListener(this);
		TextField_Result.addActionListener(this);
		TextField_Result.setFont(new Font("仿宋",Font.BOLD,24));
		
		//计算器按钮
		JPanel buttonsField=new JPanel();
		buttonsField.setLayout(new GridLayout(6,5,5,5));
		for(int i=0;i<signs.length;i++){
			buttons[i]=new JButton(signs[i]);
			buttonsField.add(buttons[i]);
			buttons[i].setBackground(color1);
			buttons[i].setFont(new Font("宋体",Font.BOLD,22));
			buttons[i].setBorder(BorderFactory.createLineBorder(color5));//设置边框颜色
		}
		//中间按钮颜色覆盖
		for(int j=11;j<=26;j=j+5){
			for(int i=0;i<3;i++){
				buttons[j+i].setBackground(color4);
			}
		}
		//等号颜色覆盖
		buttons[29].setBackground(color2);
	
		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(TextField_Result,BorderLayout.NORTH);
		frame.getContentPane().add(buttonsField,BorderLayout.CENTER);
		
		for(int i=0;i<signs.length;i++){
			buttons[i].addActionListener(this); //添加ActionEvent监听事件
			buttons[i].addKeyListener(this);    //添加键盘监听事件
					
		}
		
		for(int i=0;i<signs.length;i++){
		frame.setVisible(true);
		frame.setLocation(500,300);
		frame.setSize(500,500);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		}
	}
	//清零函数
	private void clean(){
		TextField_Result.setText(null);
	}
	
	public void actionPerformed(ActionEvent e){
		String str=e.getActionCommand();
		String text=TextField_Result.getText();
		//清零键操作
		if(str.equals(signs[3])){
			clean();
			}
		//退格键
		else if(str.equals(signs[4])){
			int text_result=text.length();
			if(text_result==0){
				TextField_Result.setText("请输入数字");
			}
			else{
				text=text.substring(0, text_result-1);
				TextField_Result.setText(text);
			}
		}
		//数字键
		else if(str.equals(signs[11])||str.equals(signs[12])||str.equals(signs[13])||str.equals(signs[16])||
				str.equals(signs[17])||str.equals(signs[18])||str.equals(signs[21])||str.equals(signs[22])||
				str.equals(signs[23])||str.equals(signs[27])){
			if(text.indexOf("请")>=0){
				clean();
				TextField_Result.setText(str);
			}
			else
			{
				TextField_Result.setText(text+str);
			}
		}
		//小数点
		else if(str.equals(signs[28])){
			TextField_Result.setText(text+str);
		}
		//百分数
		else if(str.equals(signs[1])){
			double result = Double.parseDouble(text);
			result=result/100;
			String result_s=String.valueOf(result);
			TextField_Result.setText(result_s);
			
		}
		//平方
		else if(str.equals(signs[0])){
			double result = Double.parseDouble(text);
			result=result*result;
			String result_s=String.valueOf(result);
			TextField_Result.setText(result_s);
		}
		//余弦函数
		else if(str.equals(signs[15])){
			double result = 0;
			if(text.indexOf("π")>=0){
				if(text.indexOf("π")==0){
					result=Math.PI;
					}
				else{
					text=text.substring(0, text.length()-1);
					result=Double.parseDouble(text)*Math.PI;
					}
				}
			else{
				if(text.indexOf("°")>=0){
					text=text.substring(0, text.length()-1);
					result=Math.toRadians(Double.parseDouble(text));
					}
				else{
					result=Double.parseDouble(text);
					}
				}
			result=Math.cos(result);
			TextField_Result.setText(String.format("%.3f", result));
			}
		//正弦函数
		else if(str.equals(signs[20])){
			double result = 0;
			if(text.indexOf("π")>=0){
				if(text.indexOf("π")==0){
					result=Math.PI;
				}
				else{
					text=text.substring(0, text.length()-1);
					result=Double.parseDouble(text)*Math.PI;
				}
			}
			else{
				if(text.indexOf("°")>=0){
					text=text.substring(0, text.length()-1);
					result=Math.toRadians(Double.parseDouble(text));
					}
				else{
					result=Double.parseDouble(text);
				}
			}
			result=Math.sin(result);
			TextField_Result.setText(String.format("%.3f", result));
		}
		//阶乘
		else if(str.equals(signs[2])){
			int result_jc=0;
			try{
				int num=Integer.parseInt(text);
				int sum=1;
				while(num>1){
					sum=sum*num;
					num=num-1;
				}	
				result_jc=sum;
				String result_s=String.valueOf(result_jc);
				TextField_Result.setText(result_s);
			}
			catch(NumberFormatException ev){
				TextField_Result.setText("该运算非法，请重新输入");
			}
		}
		//倒数
		else if(str.equals(signs[5])){
			double result = Double.parseDouble(text);
			if(result!=0){
				result=1/result;
				TextField_Result.setText(String.format("%.3f", result));
			}
			else{
				TextField_Result.setText("0没有倒数，请重新输入");
			}
		}
		//开方
		else if(str.equals(signs[6])){
			double result = Double.parseDouble(text);
			if(text.startsWith("-")){
				TextField_Result.setText("根号内的数不能为负数,请重新输入");
			}
			else{
				result=Math.sqrt(result);
				TextField_Result.setText(String.format("%.3f", result));
			}
		}
		//正负号运算
		else if(str.equals(signs[26])){
			double result = Double.parseDouble(text);
			if(result!=0){
				result=result*(-1);
				TextField_Result.setText(String.format("%.3f", result));
			}
			else{
				result=0;
			}
		}
		//可以进行多种符号、带有优先级的四则运算
	 	else if(str.equals(signs[9])||str.equals(signs[10])||str.equals(signs[14])||str.equals(signs[19])||
	 			str.equals(signs[24])||str.equals(signs[25])||str.equals(signs[7])||str.equals(signs[8])){
			TextField_Result.setText(text+str);
			}
		else if(str.equals(signs[29])){
			equal();
		}
	}
	
	//括号运算
	private void equal(){
		String text=TextField_Result.getText();
		if(text.indexOf("(")>=0){
			String regex0="\\([^\\(\\)]+\\)";
			Pattern text_p=Pattern.compile(regex0);
			Matcher text_m=text_p.matcher(text);
			while(text_m.find()){
				String group=text_m.group();
				String result=Calculate(group);
				text=text_m.replaceFirst(result);
				text_m.reset(text);
				}
			text=Calculate(text);
			TextField_Result.setText(text);
			}
		else{
			String text_t=TextField_Result.getText();
			text=Calculate(text_t);
			TextField_Result.setText(text);
			}
		}
	private String Calculate(String text){
		StringBuffer text_s=new StringBuffer();
		text_s.append(text);
		if(text.indexOf("*")>0||text.indexOf("/")>0){
			String regex1="([\\d.]+)\\s*([*/])\\s*([\\d.]+)";
			Pattern text_p=Pattern.compile(regex1);
			Matcher text_m=text_p.matcher(text_s);//将检索的信息封装到匹配对象中
			while(text_m.find()){
				double result1 = Double.parseDouble(text_m.group(1));
				double result2 = Double.parseDouble(text_m.group(3));
				String result="";
				switch(text_m.group(2)){
					case "*":
				    	result=String.valueOf(result1*result2);
				    	break;
				    case "/":
				        result=String.valueOf(result1/result2);
				        break;
				}
				text_s.replace(text_m.start(), text_m.end(), result);
				text_m.reset(text_s);
				}
			}
		//加减运算
		String regex2="([\\d.]+)\\s*([+-])\\s*([\\d.]+)";
		Pattern text_p=Pattern.compile(regex2);
		Matcher text_m=text_p.matcher(text_s);//将检索的信息封装到匹配对象中
		while(text_m.find()){
			double result1 = Double.parseDouble(text_m.group(1));
			double result2 = Double.parseDouble(text_m.group(3));
			String result="";
			switch(text_m.group(2)){
			    case "+":
				   	result=String.valueOf(result1+result2);
			        break;
			    case "-":
			    	result=String.valueOf(result1-result2);
			    	break;
			}
			text_s.replace(text_m.start(), text_m.end(), result);
			text_m.reset(text_s);
		}
		text=text_s.toString().replaceAll("\\(|\\)", "");
		return text;
	}
	public void keyTyped(KeyEvent e) {
		
	}
	public void keyPressed(KeyEvent e) {
		char label=e.getKeyChar();
		String sign=String.valueOf(label);
		String text=TextField_Result.getText();
		if(label==KeyEvent.VK_ENTER)
		{
			equal();
		}
		else if(label==KeyEvent.VK_BACK_SPACE) 
		{
			int text_result=text.length();
			if(text_result==0){
				TextField_Result.setText("请输入数字");
			}
			else{
				text=text.substring(0, text_result-1);
				TextField_Result.setText(text);
			}			
		}
		else if(label==127){
			clean();
		}
		else if(label>=KeyEvent.VK_0&&label<=KeyEvent.VK_9){
			inPut(sign);
		}
		else if(label==45){
			TextField_Result.setText(text+"-");
		}
		else if(label==61){
			TextField_Result.setText(text+"+");
		}
		else if(label==91){
			TextField_Result.setText(text+"(");
		}
		else if(label==93){
			TextField_Result.setText(text+")");
		}
		else if(label==59){
			TextField_Result.setText(text+"*");
		}
		else if(label==92){
			TextField_Result.setText(text+"/");
		}
	}
	public void keyReleased(KeyEvent e) {
		
	}
	public void inPut(String str){
		String text=TextField_Result.getText();
		if(TextField_Result.getText().equals("0"))
		{
			clean();
			TextField_Result.setText(str);							
		}
		else if(text.indexOf("请")>=0){
			clean();
			TextField_Result.setText(str);
		}
		else
		{
			TextField_Result.setText(text+str);
		}
	}
	public static void main(String args[]){
		new Calculator();
	}
}





		
		

